function AjaxGrid(id, RowsPerPage, RowCount, DataMethodType, DataMethodName, Sort, Order)
{
	AjaxGrid.TotalRowId='TotalId';
	var Height=0;
	var ResetHeight=false;
	this.ShowSelector=false;
	this.ShowExpander=false;
	this.IdColumn=null;
	this.Columns=new Array();
	this.DisplayHeadings=true;
	this.SingleSelection=false;
	this.RowClickSelects=false;
	this.CustomPaging=false;
	this.OnRowClick=null;
	this.PageCount=1;
	this.PageData=null;
	this.NewData=[];
	this.ModifiedData=[];
	this.NoData='No Data';
	this.PreLoad='';	
	this.Loaded=false;
	this.Editable=false;
	var PageIdx=0;
	this.SelectedRows=[];
	this.Action='None';
	var RowStyles=['GridRow','GridRowAlt'];
	var Grid=el(id+'_Grid');
	var Content=el(id+'_Content');
	var o=this;
	var x,y;
	this.Message='';
	var FirstRender=true;
	this.PageGroupSize=10;
	var cpg=0;				//CurrentPageGroup	0 based
	var AscImg=ImageUrl('Asc.gif');
	var AscGreyImg=ImageUrl('AscGrey.gif');
	var DescImg=ImageUrl('Desc.gif');
	var DescGreyImg=ImageUrl('DescGrey.gif');
	var MinusImg=ImageUrl('Minus.gif');
	var AddImg=ImageUrl('Add.gif');
	var SaveImg=ImageUrl('Save.gif');
	var DeleteImg=ImageUrl('Delete.gif');
	this.Controls=new Object();
	this.OptionPopup;
	this.SetRowsPerPage=function(r)
	{
		RowsPerPage=r;
		ResetHeight=true;
		this.GetData();
	}
	this.SetTotalCount=function(c)	//Set the TotalCount, and recalc the PageCount
	{
		RowCount=c;
		this.PageCount=1;
		if(RowsPerPage!='-1')
		{
			this.PageCount=parseInt(RowCount/RowsPerPage);
			if((RowCount%RowsPerPage)>0)
				this.PageCount++;
		}
		if(PageIdx>0&&PageIdx>(this.PageCount-1))		//Make sure the Current Page is never greater than the PageCount
			PageIdx=(this.PageCount-1);
	}
	this.GetPage=function(p)		//Get the Data for Page p
	{
		var pgs=this.PageGroupSize;
		var pc=this.PageCount;
		if(p<0)
			p=0;
		if(p>=pc)
			p=pc-1;
		var gr=this.PageGroupRange();
		if(p<gr.s||p>=gr.e)
			cpg=parseInt(p/pgs);
		PageIdx=p;
		if(PageIdx==pc-1&&RowsPerPage>30)
			ResetHeight=true;
		this.GetData();
	}
	this.GotoPageGroup=function(g)
	{
		var pgs=this.PageGroupSize;
		var p;		
		if(g>cpg)
			p=(g*pgs);
		else
			p=((g+1)*pgs)-1;
		cpg=g;
		this.GetPage(p);
	}
	this.PageGroupRange=function()
	{
		var c=this.PageCount;
		var pgs=this.PageGroupSize;
		var si=(cpg*pgs);
		if(si>=c)
			si=(c-pgs)>=0?c-pgs:0;				//min index 0 based
		var ei=(si+pgs)>c?c:si+pgs;				//max index+1
		return {s:si,e:ei}
	}
	this.SortColumn=function(cx)
	{
		var c=this.Columns[cx];
		if(Sort==c.Sort)			//if resorting the current sorted Column (Toggle)
		{
			if(Order=='Asc')
				c.Order='Desc';
			else
				c.Order='Asc';
		}
		Sort=c.Sort;
		Order=c.Order;
		this.GetData();
	}
	this.SetSort=function(s,o)
	{
		Sort=s;
		Order=o;
	}
	this.GetData=function(FirstTimeOnly)			//Get the Data for the current page, using the current sort settings
	{
		if(this.Loaded&&FirstTimeOnly)
			return;
		this.Loaded=true;
		x=document.documentElement.scrollLeft;
		y=document.documentElement.scrollTop;
		if(DataMethodType==null||DataMethodName==null)
		{
			alert('Ajax Grid ('+id+') Error: Invalid Server Method.');
			return;
		}
		Height=Content.clientHeight;
		ShowLoading(Content);
		var p=this.Parameters;
		if(p)
		{
			for(i=0;i<p.length;i++)
			{
				var e=el(p[i].Source);
				if(e==null)
					e=window[p[i].Source];
				if(e!=null)
				{
					if(e.type=='checkbox')
						p[i].Value=e.checked;
					else if(e.Type=='Calendar')
						p[i].Value=e.Date;
					else if(e.value!=null)
						p[i].Value=e.value;
				}
			}
		}
		var request=new Object();
		request.DataMethodType=DataMethodType;
		request.DataMethodName=DataMethodName;
		
		var gi=new Object();
		gi.Page=PageIdx;
		gi.RowsPerPage=RowsPerPage;
		gi.Parameters=this.Parameters;
		gi.SelectedRowIds=this.SelectedRows;
		gi.Action=this.Action;
		gi.CustomPaging=this.CustomPaging;
		gi.Columns=this.Columns;
		gi.Sort=Sort;
		gi.Order=Order;
		gi.ModifiedRows=this.ModifiedData;
		gi.NewRows=this.NewData;
		request.GridInfo=gi;
		Web.Ajax.Controls.AjaxGrid.GetGridData(request,this.SetData);
	}
	this.DeleteSelectedRows=function()
	{
		this.Action='Delete';
		this.GetData();
	}
	this.DeleteNewRow=function(i)
	{
		if(this.NewData&&this.NewData.length>i)
			this.NewData.splice(i,1);
		this.Render();
	}
	this.GetSelectedRowCount = function() 
	{
		if (!this.SelectedRows)
			return 0;
		return this.SelectedRows.length;
	}
	this.Delete = function(m, l) {
		if (m) {
			if (this.GetSelectedRowCount() == 0) {
				alert('Please select some items to delete.');
				return;
			}
			if (!confirm(m))
				return;
		}
		if (l) {
			for (var i = (this.PageData.length - 1); i >= 0; i--) {
				if (jQuery.inArray(this.PageData[i][this.IdColumn], this.SelectedRows)!=-1) {
					this.PageData.splice(i, 1);
				}
			}
			this.SelectedRows = [];
			this.Render();
		}
		else {
			this.Action = 'Delete';
			this.GetData();
		}
	}
	this.IsValid=function()
	{
		if(this.Columns)
		{
			var cnt=0;
			if(this.PageData)
				cnt+=this.PageData.length;
			if(this.NewData)
				cnt+=this.NewData.length;
			for(var i=0;i<this.Columns.length;i++)
			{
				var c=this.Columns[i];
				if(c.Editable)
				{
					for(var j=0;j<cnt;j++)
					{
						var cell=el(this.GetCellHtmlId(j,c.Binding));
						if(cell&&cell.className=='GridDataError')
							return false;
					}
				}
			}
		}
		return true;
	}
	this.Save=function()
	{
		this.SetActionMessage('');
		if(!this.IsValid())
		{
			this.SetActionMessage('Please correct any validation errors.');
			return;
		}
		this.Action='Save';
		this.GetData();
	}
	this.SetData = function(ret) {
		o.PageData = seval(ret.PageData);
		o.SetTotalCount(ret.TotalCount);
		o.Message = ret.Message;
		if (ret.ClearSelectedIds)
			o.SelectedRows = [];
		if (ret.SetSelectedIds)
			o.SelectedRows = ret.SelectedIds;
		if (ret.ClearModifiedRows) {
			o.ModifiedData = [];
			o.NewData = [];
		}
		if (ret.Columns)
			o.Columns = ret.Columns;
		if (ret.OnComplete)
			eval(ret.OnComplete);
		o.Render();
		o.Action = 'None';
		if (o.OnComplete)
			o.OnComplete();
	}
	this.IsSelected=function(row)
	{
		var idcol=this.IdColumn;
		var val;
		if(!idcol||!row)
			return false;
		val=row[idcol];
		var srows=this.SelectedRows;
		if(!srows)
			return false;
		for(var i=0;i<srows.length;i++)
		{
			if(srows[i]==val)
				return true;
		}
		return false;
	}
	this.ResetRowCss=function()
	{
		var l=this.PageData.length;
		for(var i=0;i<l;i++)
			el(id+'_Row_'+i).className=this.GetRowCss(i);
	}
	this.SelectRow=function(idx)
	{
		var css=this.GetRowCss(idx);
		var row=el(id+'_Row_'+idx);
		var cb=el(id+'_Chk_'+idx);
		
		var val=this.GetRowId(idx);
		if(val=='')
		{
			alert('Cannot Select Row. The IdColumn property must be set on the AjaxGrid.');
			return;
		}
		if(!this.SelectedRows)
			this.SelectedRows=[];
		if(this.SingleSelection)
		{
			this.ResetRowCss();
			this.SelectedRows=[val];
			row.className='GridRowSelected';
			if(cb)
				cb.checked=true;
			return;
		}
		var r=-1;		
		var srows=this.SelectedRows;
		for(i=0;i<srows.length;i++)
		{
			if(srows[i]==val)
			{
				r=i;
				srows.splice(i,1);
				row.className=css;
				if(cb!=null)
				{
					cb.checked=false;
					if(this.Editable)
						this.CellChanged(idx,'Selected',false)
				}
				break;
			}
		}
		if(r==-1)
		{
			srows[srows.length]=val;
			row.className='GridRowSelected';
			if(cb!=null)
			{
				cb.checked=true;
				if(this.Editable)
					this.CellChanged(idx,'Selected',true)
			}
		}
	}
	this.ShowRow=function(idx, visible)
	{
		var row=el(id+'_Row_'+idx);
		//row.style.display=visible?Web.Ajax.RowDisplayValue:'none';
		row.style.display = visible ? '' : 'none';
	}
	this.ExpandRow=function(idx,Expand)
	{
		var pid=this.GetRowId(idx);
		var row=this.GetRow(pid);
		if(!row)
			return;
		if(row.Expand==null)
			row.Expand=true;
		var e=row.Expand;
		e=!e;
		if(Expand!=null)
			e=Expand;
		for(var i=0;i<this.PageData.length;i++)
		{
			if(this.PageData[i]['ParentId']==pid)
				this.ShowRow(i,e);
		}
		row.Expand=e;
		var td=el(id+'_exp_'+idx);
		if (td)
		{
			if(e)
				td.className = td.className.replace(/GridExpanderClosedParent/g, 'GridExpanderOpenParent')
			else
				td.className = td.className.replace(/GridExpanderOpenParent/g, 'GridExpanderClosedParent')
		}
	}
	this.RenderHeadings = function() {
		var html = '';
		if (!this.DisplayHeadings)
			return html;
		html += '<tr>';
		if (this.ShowExpander)
			html += '<td class="GridHeading" style="width:20px;" >&nbsp;</td>';
		if (this.ShowSelector)
			html += '<td class="GridHeading" style="width:20px;" >&nbsp;</td>';
		for (i = 0; i < this.Columns.length; i++)	//For each column
		{
			var c = this.Columns[i];
			if (!c.Visible)
				continue;
			var Sortable = (c.Sort != null && c.Sort != '');

			var css = 'GridHeading ';
			var help = '';
			var txtasc = 'Click Sort Ascending';
			var txtdesc = 'Click Sort Descending';
			
			if (Sortable) {
				if (c.Order == 'Asc' || c.Order == 'asc') {
					css += (Sort != c.Sort ? 'SortAsc' : 'SortedAsc');
					help = Sort != c.Sort ? txtasc : txtdesc;
				}
				if (c.Order == 'Desc' || c.Order == 'desc') {
					css += (Sort != c.Sort ? 'SortDesc' : 'SortedDesc');
					help = Sort != c.Sort ? txtdesc : txtasc;
				}
			}

			html += '<td class="' + css + '" title="' + help + '" ';
			var style = 'text-align:' + c.HeadingAlign + ';';
			if (Sortable) {
				html += 'onclick="' + id + '.SortColumn(' + i + ');" ';
				style += 'cursor:pointer;';
			}
			var w = c.Width;
			if (w != null && w != '')
				style += 'width:' + c.Width + ';'
			html += 'style="' + style + '">';
			if (c.Name == '')
				html += '&nbsp;';
			else
				html += c.Name;
			html += '</td>';
		}
		html += '</tr>';
		return html;
	}
	function EncodeItem(value)
	{
		if(value==null)
			return '';
		return value.replace(/\n/g,'<br>');
	}
	this.GetRowId=function(idx)
	{
		if(!this.IdColumn||!this.PageData||idx>=this.PageData.length)
			return '';
		return this.PageData[idx][this.IdColumn];		    
	}
	this.GetRow=function(id)
	{
		if(!this.IdColumn||!this.PageData)
			return null;
		for(var i=0;i<this.PageData.length;i++)
			if(this.PageData[i][this.IdColumn]==id)
				return this.PageData[i];
	}
	this.GetRows = function(c, v) 
	{
		var rl = [];
		if (this.PageData) 
		{
			for (var i = 0; i < this.PageData.length; i++)
				if (this.PageData[i][c] == v)
					rl[rl.length]=this.PageData[i];
		}
		return rl;
	}
	this.GetValue=function(id, col)
	{
		var row=this.GetRow(id);
		if(row)
			return row[col];
	}
	this.RowClickScript=function(idx)
	{
		var s='';
		var val=this.GetRowId(idx);	
		if(this.RowClickSelects)
			s+=id+'.SelectRow('+idx+');';
		var rc=this.OnRowClick;
		if(rc)
		{
			if(val)
				val=val.replace(/\\/g,'\\\\'); 
			rc=rc.replace(/string/g,'\''+val+'\'');
			rc=rc.replace(/params/g,val);
			s+=rc;
		}
		if(s=='')
			return s;
		return 'onclick="'+s+'"';
	}
	this.ColClickScript=function(idx,c)
	{
		var val=this.GetRowId(idx);	
		if(!c.OnClick||c.OnClick=='')
		{
			if (this.EditUrl)
				return 'onclick="url(\''+this.EditUrl+'\').p(\'Id\',\''+val+'\').go();"';
			
				//return 'onclick="location.href=\''+this.EditUrl+'?'+encrypt('Id='+val)+'\'"';
			return '';
		}
		if(val==null)
			return;
		if(val.match(/[a-zA-Z]/g)&&val.indexOf('\'')==-1)
			val = '\'' + val + '\'';
		val= val.replace(/string/g, '\'' + val + '\'');
		return 'onclick="'+c.OnClick+'('+val+')"';
	}
	this.GetRowCss=function(idx)
	{
		var delta=0;
		if(this.ShowExpander)
		{
			if(idx>0&&this.PageData[idx]['ParentId'])
				return this.GetRowCss(idx-1);
			for(var i=0;i<(idx+1);i++)
			{
				if(this.PageData[i]['ParentId'])
					delta++;
			}
		}
		return RowStyles[((idx-delta)%RowStyles.length)];
	}
	this.GetColumn=function(b)
	{
		if(!this.Columns)
			return null;
		for(var i=0;i<this.Columns.length;i++)
		{
			if(this.Columns[i].Binding==b)
				return this.Columns[i];
		}
	}
	this.CellChanged=function(idx,b,v,n)
	{
		var r;
		var c=this.GetColumn(b);
		if(n)
			r=this.NewData[idx-this.GetNewRowHtmlIdx(0)]; 
		else
		{
			var rowid=this.GetRowId(idx);
			for(var i=0;i<this.ModifiedData.length;i++)
			{
				if(this.ModifiedData[i][this.IdColumn]==rowid)
					r=this.ModifiedData[i];
			}
			if(!r)
			{
				this.ModifiedData[this.ModifiedData.length]=this.PageData[idx];
				if(this.ModifiedData.length>0)
					r=this.ModifiedData[this.ModifiedData.length-1];
			}
		}
		if(r&&r[b]!=v)
		{
			var cell=el(this.GetCellHtmlId(idx, b));
			if(cell)
				cell.className='GridData';
			if(c&&c.Required&&(v==''))
			{
				var message='This is a required field.'
				if(cell)
				{
					cell.className='GridDataError';
					cell.title=message;
				}
				return;
			}
			r.ModifiedRow=true;
			r[b]=v;
			if(!n)
			{
				r.RowState='Modified';
				r.RowStateImage=ImageHtml(ImageUrl('RedDot.gif'),null,null,'This row has been modified. You will need to save your changes.');
				var statecol=el(this.GetCellHtmlId(idx,'RowState'));
				if(statecol)
					statecol.innerHTML='Modified';
				var stateimgcol=el(this.GetCellHtmlId(idx,'RowStateImage'));
				if(stateimgcol)
					stateimgcol.innerHTML=r.RowStateImage;
			}
		}
		if(c&&c.OnChange!=null&&window[c.OnChange]!=null)
			eval(c.OnChange+'();');
	}
	this.RenderInput = function(c, v, idx, n) {
		var html = '';
		var type = 'text';
		if (c.Type)
			type = c.Type;
		var style = '';
		if (c.Align)
			style += 'text-align:' + c.Align + ';';
		var w = c.Width;
		if (w != null && w != '')
			style += 'width:' + c.Width + ';';
		var setstr = 'value="' + v + '"';
		var getstr = 'this.value';
		if (type == 'checkbox')
			getstr = 'this.checked';
		type = type.toLowerCase();
		var onchange = 'onblur="' + id + '.CellChanged(' + idx + ',\'' + c.Binding + '\',' + getstr + ',' + (n ? n : 'null') + ');"';
		if (type == 'textarea') {
			html += '<textarea style="height:100%;" class="GridInput" ' + onchange + '>';
			html += v;
			html += '</textarea>';
		}
		else if (type == 'calendar') {
			var cid = id + '_' + idx + '_' + c.Binding;
			var cal = new Calendar(cid, 0, 0, 'br');
			cal.Date = seval(v);
			cal.OnDateChanged = id + '.CellChanged(' + idx + ',\'' + c.Binding + '\',' + id + '.Controls[\'' + cid + '\'].Date,' + (n ? n : 'null') + ');';
			html += cal.GetClientHtml();
			window[cid] = cal;
			this.Controls[cid] = cal;
		}
		else if (type == 'select')	//todo
		{
			html += '<select class="GridInput" ' + onchange + '>';
			if (c.Options) {
				for (var i = 0; i < c.Options.length; i++) {
					html += '<option value="' + c.Options[i].Value + '" ' + ((v == c.Options[i].Value) ? 'selected' : '') + '>' + c.Options[i].Text + '</option>';
				}
			}
			html += '</select>';
		}
		else {
			if (type == 'checkbox') {
				onchange = onchange.replace(/onblur/g, 'onclick');
				setstr = (v && v.toLowerCase() == 'true' ? 'checked' : '');
				getstr = 'this.checked';
				style += 'width:auto;';
			}
			html += '<input type="' + type + '" ' + setstr + ' style="' + style + '" class="GridInput" ' + onchange + ' />';
		}
		return html;
	}
	this.GetCellHtmlId=function(idx,b)
	{
		return id+'_Row_'+idx+'_'+b;
	}
	this.RenderOptionColumn=function(o, rid, bind)
	{
		o=seval(o);
		var html='&nbsp;';
		if(!o)
			return html;
		if((!o.Items||o.Items.length==0)&&!o.OnClick)
			return html;
		var click=o.OnClick;
		if(o.Items)
			click=id+'.RenderOptionsPopup(\''+rid+'\', \''+bind+'\');';
		html='<img id="'+id+rid+bind+'" onclick="'+click+'" src="'+ImageUrl('DropDown.gif')+'" style="padding: 0;"></img>';	    
		return html;
	}
	this.RenderOptionsPopup = function(rid, bind)
	{
		var o = this.GetValue(rid, bind);
		o = seval(o);
		if (!o || !o.Items)
			return;
		var e = Append('div', id + 'Options', 'PopupMenuPanel');
		var html = '<div class="PopupMenu">';
		for (var i = 0; i < o.Items.length; i++)
		{
			var opt = o.Items[i];
			html += '<div onclick="' + opt.OnClick + '" class="MenuItem ' + (opt.Css ? opt.Css : '') + '">';
			if (opt.Resource)
				html += ImageHtml(ImageUrl(opt.Resource), 'MenuItemImage') + '&nbsp;';
			html += opt.Text + '</div>';
		}
		html += '</div>';
		if (!this.OptionPopup)
			this.OptionPopup = new PopupMenu(id + 'Options', 5, 0, 'tr');
		this.OptionPopup.ShowFromNewSource(el(id + rid + bind), html);
	}
	this.RenderCell = function(r, idx, n, c, RowId) {
		var html = '';
		var cclass = 'GridData';
		if (!c.Visible)
			return html;
		var t = c.Template;
		var title = '';
		var itemHtml = EncodeItem(r[c.Binding]);
		if (t != null && t != '') {
			itemHtml = t.replace(/#VALUE#/g, ('' + itemHtml));
			itemHtml = itemHtml.replace(/#ID#/g, ('' + RowId));
		}
		if (c.Javascript)
			itemHtml = eval(itemHtml);
		if (c.Function)
			itemHtml = eval(c.Function)(RowId, r);
		var style = '';
		if (c.Css)
			style += c.Css;
		if (c.Align != '')
			style += 'text-align:' + c.Align + ';';
		if (c.Padding && c.Padding != '')
			style += 'padding:' + c.Padding + ';';
		if (c.VerticalAlign != '')
			style += 'vertical-align:' + c.VerticalAlign + ';';
		if (c.Editable && (r.Editable != 'false' && r.Editable != 'False')) {
			itemHtml = this.RenderInput(c, itemHtml, idx, n);
			cclass = "GridDataInput";
		}
		if (itemHtml == '')
			itemHtml = '&nbsp;';
		if (c.MaxLength && itemHtml.length > c.MaxLength) {
			title = itemHtml;
			itemHtml = itemHtml.substring(0, c.MaxLength) + '...';
		}
		if (c.Binding == 'Options' || c.Type == 'Options')
			itemHtml = this.RenderOptionColumn(r[c.Binding], RowId, c.Binding);
		if (RowId == AjaxGrid.TotalRowId) {
			if (itemHtml == '&nbsp;' || itemHtml == AjaxGrid.TotalRowId) {
				cclass = 'GridDataTotalEmpty';
				itemHtml = '&nbsp;';
			}
			else if (itemHtml.indexOf('Total') > -1) {
				style = '';
				cclass = 'GridTotalLabel';
			}
			else
				cclass = 'GridDataTotal';
		}
		html += '<td id="' + this.GetCellHtmlId(idx, c.Binding) + '" class="' + cclass + '" ' + (title ? ('title="' + title.replace(/\"/g, '&quot;').replace(/<br>/g, '\r\n') + '"') : '') + ' style="' + style + '" ' + this.ColClickScript(idx, c) + '>' + itemHtml + '</td>';
		return html;
	}
	this.RenderRow = function(r, idx, n)
	{
		if (r == null) return '';
		var html = '';
		var RowId = this.GetRowId(idx);
		var cols = this.Columns;
		var sel = this.IsSelected(r);
		var css = this.GetRowCss(idx);
		if (RowId == AjaxGrid.TotalRowId)
			css = 'GridRowTotal';
		var onclick = this.RowClickScript(idx);
		var nextrow = null;
		if (!n)
			nextrow = this.PageData[idx + 1];
		var rowstyle = 'style="';
		html += '<tr id="' + id + '_Row_' + idx + '" class="' + (r.RowCss ? r.RowCss : (sel ? 'GridRowSelected ' : css)) +'" ' + onclick + ' ' + rowstyle + '"  >';
		if (this.ShowExpander)
		{
			var ParentWithChildren = (r['ParentId'] == null && nextrow != null && nextrow['ParentId'] == this.GetRowId(idx));
			var Child = r['ParentId'] != null;

			var ts = 'GridExpanderEmptyRoot';
			if (ParentWithChildren)
			{
				ts = r['Expand'] == 'false' ? 'GridExpanderClosedParent' : 'GridExpanderOpenParent';
			}
			else if (Child)
			{
				if (!nextrow || (nextrow && nextrow['ParentId'] == null))
					ts = 'GridExpanderLastChild';
				else
					ts = 'GridExpanderChild';
			}
			html += '<td class="GridExpanderColumn GridData ' + ts + '" id="' + id + '_exp_' + idx + '"';
			if (ParentWithChildren)
				html += ' onclick="' + id + '.ExpandRow(' + idx + ');" ';
			html += '>';

			html += '</td>';
		}
		if (this.ShowSelector)
		{
			html += '<td class="GridData" style="width:20px;text-align:center;">';
			if (n)
			{
				html += ImageHtml(DeleteImg, null, id + '.DeleteNewRow(' + (idx - this.GetNewRowHtmlIdx(0)) + ');');
			}
			else if (r['EnableSelection'] != 'false')
			{
				html += '<input class="GridSelector" name="' + id + 'Select" type="' + (this.SingleSelection ? 'radio' : 'checkbox') + '" id="' + id + '_Chk_' + idx + '" ' + (sel ? 'checked' : '');
				if (!this.RowClickSelects)
					html += ' onclick="' + id + '.SelectRow(' + idx + ');"';
				html += ' />';
			}
			html += '</td>';
		}
		for (var j = 0; j < cols.length; j++)
			html += this.RenderCell(r, idx, n, cols[j], RowId);
		html += '</tr>';
		return html;
	}
	this.RenderRows=function()
	{
		var html='';
		var data=this.PageData;
		if(!data)
			return html;
		var count=this.PageData.length;
		if(RowsPerPage>0)
			count=RowsPerPage;
		for(i=0;i<count;i++)
		{
			html+=this.RenderRow(data[i],i);
		}
		return html;
	}
	this.GetNewRowHtmlIdx=function(i)
	{
		if(this.PageData)
			return this.PageData.length+i;
		return i;
	}
	this.RenderNewRows=function()
	{
		var html='';
		var data=this.NewData;
		for(i=0;i<data.length;i++)
		{
			html+=this.RenderRow(data[i],this.GetNewRowHtmlIdx(i),true);
		}
		return html;
	}
	this.RenderFooter=function()
	{
		var c=this.PageCount;
		var pgs=this.PageGroupSize;
		var m=this.Message;
		if((c<2&&(m==''||m==null))||RowCount<1)
			return '';
		var html='<tr><td colspan="26"><div class="GridSpacer" id="'+id+'_Spacer" style="height:0px;"><!-- --></div></td></tr>';
		html+='</table>';
		html+='<table style="width:100%;" cellspacing="0" cellpadding="0" class="GridFooter">';
			html+='<tr>';
				html+='<td style="width:33%;text-align:left;">&nbsp;</td>'
				html+='<td style="width:33%;" id="'+id+'_Footer">';
				if(c>1)	//If there is more than one page, show the page links.
				{
					var style='cursor:pointer;';
					if(PageIdx==0)
						style+='visibility:hidden;';
					html+=ImageHtml(ImageUrl('FirstPage.gif'),'GridPageImg',id+'.GetPage(0);','First Page',null,style);
					html+=ImageHtml(ImageUrl('PrevPage.gif'),'GridPageImg',id+'.GetPage('+(PageIdx-1)+');','Previous Page',null,style);
					var gr=this.PageGroupRange();
					if(c>pgs&&cpg>0)	//Last PageGroup link needed.
						html+='<span class="GridLink" onclick="'+id+'.GotoPageGroup('+(cpg-1)+');">...</span>';					
					for(i=gr.s;i<gr.e;i++)	//Page Links
						html+='<span class="GridLink'+(i==PageIdx?'On':'')+'" onclick="'+id+'.GetPage('+i+');" title="'+(i==PageIdx?('Page '+(PageIdx+1)+' of '+c):('Get Page '+(i+1)))+'">'+(i+1)+'</span>';
					if(gr.e<c)			//Next PageGroup link Needed
						html+='<span class="GridLink" onclick="'+id+'.GotoPageGroup('+(cpg+1)+');">...</span>';
					style='cursor:pointer;';
					if(PageIdx==(c-1))
						style+='visibility:hidden;';
					html+=ImageHtml(ImageUrl('NextPage.gif'),'GridPageImg',id+'.GetPage('+(PageIdx+1)+');','Next Page',null,style);
					html+=ImageHtml(ImageUrl('LastPage.gif'),'GridPageImg',id+'.GetPage('+(c-1)+');','Last Page',null,style);
				}
				html+='</td>';
				var from=(RowsPerPage*(PageIdx));
				var to=from+RowsPerPage;
				if(to>RowCount||to==-1)
					to=RowCount;
				html+='<td style="width:33%;text-align:right;white-space:nowrap;">'
				if(RowCount>0)
					html+='('+(from+1)+' - '+to+') of '+RowCount+'&nbsp;'
				html+='</td>'
			html+='</tr>';
			if(m!=null&&m!='')
				html+='<tr><td class="Error" colspan="3">'+m+'</td>'+'</tr>';
		return html;
	}
	this.RenderActions=function()
	{
		var show=false;
		var html='';
		html+='<div class="GridActions">';
		html+='<span id="'+id+'_ActionMessage" class="Error" style="float:left;" ></span>';
		if(this.ShowAdd)
		{
			html+=ImageHtml(AddImg,'GridAction',id+'.AddRow();','Add a New Row');			
			show=true;
		}
		if(this.ShowDelete)
		{
			html+=ImageHtml(DeleteImg,'GridAction',id+'.Delete(\'Are you sure you want to delete the selected rows?\');','Delete selected rows');			
			show=true;
		}
		if(this.ShowSave)
		{
			html+=ImageHtml(SaveImg,'GridAction',id+'.Save();','Save Changes');			
			show=true;
		}
		html+='</div>';
		if(!show)
			return '';
		return html;
	}
	this.Render=function()
	{
		this.Controls=new Object();
		var html='<table cellpadding="0" cellspacing="0" width="100%" class="GridTable">';
		if((this.PageData!=null&&this.PageData.length>0)||(this.NewData!=null&&this.NewData.length>0))
		{
			html+=this.RenderHeadings();
			html+=this.RenderRows();
			html+=this.RenderNewRows();
			html+=this.RenderFooter();
		}
		else
		{
			if(this.Message)
				html+='<tr><td><div class="Error">'+this.Message+'</div></td></tr>';
			else if(this.Loaded)
				html+='<tr><td><div class="NoData">'+this.NoData+'</div></td></tr>';
			else
				html+='<tr><td><div class="NoData">'+this.PreLoad+'</div></td></tr>';
				
			PageIdx=0;
			cpg=0;
		}
		html+='</table>';
		html+=this.RenderActions();
		Content.innerHTML=html;		
		for(var p in this.Controls)
		{
			var c=this.Controls[p];
			if(c.Init)
				c.Init();
		}
		if(this.ShowExpander&&this.PageData!=null&&this.PageData.length>0)
		{
			for(var i=0;i<this.PageData.length;i++)
			{
				if(this.PageData[i]['ParentId']==null)
				{
					var Expand=this.PageData[i].Expand;
					this.ExpandRow(i,Expand!='false'&&Expand!=false);
				}
			}
		}
		var h=Content.clientHeight;
		
		var s=el(id+'_Spacer');
		if(Height-h>5) //Ignore small height changes
		{
			if(h>Height||ResetHeight)
			{
				Height=h;
				ResetHeight=false;
			}
			else
				if(s)
					s.style.height=(Height-h)+'px';
		}
		if(FirstRender)		//Don't do a scroll if this is the first render
			FirstRender=false;
		else
			scrollTo(x,y);

	}
	this.Clear=function()
	{
		this.PageData=null;
		this.Message=null;
		this.ClearSelection();
	}
	this.ClearSelection=function()
	{
		this.SelectedRows=[];
		this.Render();
	}
	this.AddRow = function(d, unique)
	{
		if (!this.NewData)
			this.NewData = [];
		if (unique)
		{
			var er = this.GetRow(d[this.IdColumn])
			if (er != null)
				return;
			for (var i = 0; i < this.NewData.length; i++)
			{
				if (this.NewData[i][this.IdColumn] == d[this.IdColumn])
					return;
			}
		}
		if (this.NewData.length >= this.MaxNewRows)
			return;
		var r = new Object();
		if (this.Columns)
		{
			for (var i = 0; i < this.Columns.length; i++)
			{
				var c = this.Columns[i];
				if (c.DefaultValue)
					r[c.Binding] = c.DefaultValue;
				if (d != null && d[c.Binding] != null)
					r[c.Binding] = '' + d[c.Binding];
			}
		}
		r.NewRow = true;
		r.RowState = 'New';
		r.RowStateImage = ImageHtml(ImageUrl('RedDot.gif'), null, null, 'This row is new and has not been saved.');
		this.NewData[this.NewData.length] = r;
		this.Render();
	}
	this.SetActionMessage=function(m)
	{
		var e=el(id+'_ActionMessage');
		if(e)
			e.innerHTML=m;
	}
}
AjaxGrid.prototype=new AjaxControl();
